﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using KNXObjects.Enum;
using KNXObjects.Addresses;

namespace KNXObjects
{
    public abstract class ObjectBase : INotifyPropertyChanged
    {
        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Propertiess

        public FlagsEnum Flags { get; set; }
        public abstract string DataPointID { get; }
        public abstract string DataPointEISName { get; }
        public string ID { get; set; }
        public GroupAddressType GroupAddress { get; set; }
        public string Name { get; set; }
        protected object Value { get; set; }
        #endregion

        #region Methods

        public abstract override string ToString();
        public abstract void SetValue(string value);
        public T GetValue<T>()
        {
            return (T)Value;
        }

        #endregion

        public ObjectBase(string id, string groupAddress, string name, string flags)
        {                        
            this.ID = id;
            this.GroupAddress = new GroupAddressType(groupAddress);
            this.Name = name;
            this.Flags = GetFlagsEnum(flags);
        }
        public ObjectBase()
        {

        }
        private FlagsEnum GetFlagsEnum(string flags)
        {
            if (flags == null)
                return FlagsEnum.Default;
            flags = flags.Trim();
            if (flags.Length == 0)
                return FlagsEnum.Default;
            else
            {
                FlagsEnum f = new FlagsEnum();
                char[] chars = flags.ToCharArray();
                for (int i = 0; i < chars.Length; i++)
                {
                    switch (chars[i])
                    {
                        case 'c':
                            f |= FlagsEnum.Communication;
                            break;
                        case 'r':
                            f |= FlagsEnum.Read;
                            break;
                        case 'w':
                            f |= FlagsEnum.Write;
                            break;
                        case 't':
                            f |= FlagsEnum.Transmit;
                            break;
                        case 'u':
                            f |= FlagsEnum.Update;
                            break;
                        case 'f':
                            f |= FlagsEnum.Force;
                            break;
                        case 'i':
                            f |= FlagsEnum.Init;
                            break;
                    }
                }
                return f;

            }
        }


        public static ObjectBase GetConcreteObject(string id, string groupAddress, string name, string type, string flags)
        {
            ObjectBase newObject = null;
            switch (type)
            {
                case "":
                case "EIS1":
                case "1.001":
                    newObject = new SwitchingObject(id, groupAddress, name, flags);
                    break;
                case "EIS2":
                case "3.007":
                    newObject = new DimmingObject(id, groupAddress, name, flags);
                    break;
                case "3.008":
                    newObject = new BlindObject(id, groupAddress, name, flags);
                    break;
                case "5.001":
                    newObject = new ScaledObject(id, groupAddress, name, flags);
                    break;
                case "5.003":
                    newObject = new AngleObject(id, groupAddress, name, flags);
                    break;
                case "6.xxx":
                case "EIS14":
                    newObject = new S8Object(id, groupAddress, name, flags);
                    break;
                case "7.xxx":
                case "EIS10":
                    newObject = new U16Object(id, groupAddress, name, flags);
                    break;
                case "8.xxx":
                    newObject = new S16Object(id, groupAddress, name, flags);
                    break;
                case "EIS3":
                case "10.001":
                    newObject = new TimeObject(id, groupAddress, name, flags);
                    break;
                case "EIS4":
                case "11.001":
                    newObject = new DateObject(id, groupAddress, name, flags);
                    break;
                case "12.xxx":
                case "EIS11":
                    newObject = new U32Object(id, groupAddress, name, flags);
                    break;
                case "13.xxx":
                    newObject = new S32Object(id, groupAddress, name, flags);
                    break;
                case "14.xxx":
                    newObject = new ValueObject32(id, groupAddress, name, flags);
                    break;
                case "16.000":
                case "EIS15":
                    newObject = new StringObject(id, groupAddress, name, flags);
                    break;
            }
            return newObject;

        }

    }
}
